package sms

import (
	"com.cyt.common/library/sms/gateway"
	"com.cyt.common/library/sms/internal"
	"com.cyt.common/library/sms/strategy"
	"errors"
	"github.com/gogf/gf/frame/g"
	"github.com/gogf/gf/text/gstr"
	"github.com/gogf/gf/util/gutil"
)

type SmsClient struct {
		P         *internal.PhoneNumber
		M         *internal.Message
		Config    map[string]interface{}
		Gateway   []string
}

func NewClient(to string, params map[string]interface{}, gateways ...[]string) *SmsClient {
	s := &SmsClient{}
	s.P = formatPhoneNumber(to)
	s.M = formatMessage(params)
	if len(gateways) > 0 {
		s.Gateway = gateways[0]
	} else {
		s.Gateway = g.Cfg().GetStrings("sms.default.gateways") // 获取默认网关
	}
	return s
}

func SendSms(to string, params map[string]interface{}, gateways ...[]string) (map[string]interface{}, error) {
	client := NewClient(to, params, gateways[0])
	return client.Send()
}

func (s *SmsClient) Send() (map[string]interface{}, error) {
	results := g.Map{}
	isSuccessful := false
	gateways := formatGateways(s.Gateway)

	// 捕获网关异常
	for _, v := range gateways {
		gutil.TryCatch(func() {
			instance := &gateway.Gateway{
				To: s.P,
				Message: s.M,
			}

			gateway := GatewayMap[v]
			gatewayHandler, _ := gateway.New(instance)
			result := gatewayHandler.Send()
			results = gutil.MapMergeCopy(results, g.Map{
				v: g.Map{
					"gateway": v,
					"status": STATUS_SUCCESS,
					"result": result,
				},
			})
			isSuccessful = true
			return
		}, func(err error) {
			results = gutil.MapMergeCopy(results, g.Map{
				v: g.Map{
					"gateway": v,
					"status": STATUS_FAILURE,
					"result": err,
				},
			})
		})
		if isSuccessful == true {
			break
		}
	}

	if isSuccessful == false {
		return results, errors.New("no gateway available")
	}

	return results, nil
}

func formatPhoneNumber(number string) *internal.PhoneNumber {
	return internal.NewPhoneNumber(gstr.Trim(number), "")
}

func formatMessage(params map[string]interface{}) *internal.Message {
	return internal.NewMessage(params, TEXT_MESSAGE)
}

func formatGateways(gateways []string) []string {
	// 策略 获取 对应网关
	instance := Strategy("")
	data := &strategy.Strategy{
		Gateway: gateways,
	}
	strategyHandler, _ := instance.New(data)
	gateways = strategyHandler.Apply(gateways)
	return gateways
}

func Strategy(strategy string) strategy.Driver {
	if strategy != "" {
		return StrategyMap[strategy]
	}
	strategy = g.Cfg().GetString("sms.default.strategy")
	// 使用默认策略
	if strategy == "" {
		strategy = "order"
	}
	return StrategyMap[strategy]
}
